#ifndef CLASSFILE_H
#define CLASSFILE_H

#include <vector>
#include "ConstantPool.h"
#include "jtypes.h"

class FieldInfo;
class AttributeInfo;
class ConstantPool;
class MethodInfo;

typedef std::vector<FieldInfo*>     FieldInfoList;
typedef std::vector<AttributeInfo*> AttributeInfoList;
typedef std::vector<MethodInfo*>    MethodInfoList;
typedef std::vector<unsigned short> InterfacesList;

class ClassFile 
{
  public:
    ClassFile(const char * filename);
    static ClassFile * newClassFile(const char * classname);

    void dumpConstantPool();
    void dumpInterfaces();
    void dumpFields();
    void dumpMethods();

    void dump();

    void save();

    const char * getClassName();

    MethodInfo * addDefaultMainMethod();

    MethodInfo * getMethod(const char * methodName, 
        const char * signature);

    u2  getFieldRef(const char * klass, 
        const char * nameAndType);

    /* adding stuff into the constant pool */
    inline u2 addUtf8(const char * string) {
      return m_constantPool->addUtf8(string);
    }
    
    inline u2 addFieldRef(const char * class_name, 
        const char * field_name,
        const char * signature) {
      return m_constantPool->addFieldRef(class_name,field_name,signature);
    }

    inline u2 addMethodRef(const char * class_name, 
        const char * name,
        const char * signature) {
      return m_constantPool->addMethodRef(class_name,name,signature);
    }

    inline u2 addString(const char * string) {
      return m_constantPool->addString(string);
    }

    // TODO: try to avoid the need for the following
    inline ConstantPool * getConstantPool() { return m_constantPool; }

  private:

    ClassFile();

    ConstantPool    * m_constantPool;
    
    u2 m_access_flags;
    u2 m_this_class;
    u2 m_super_class;
    u2 m_major_version;
    u2 m_minor_version;

    InterfacesList    m_interfaces;
    FieldInfoList     m_fields;
    MethodInfoList    m_methods;
    AttributeInfoList m_attributes;
};

#endif
